package edu.kit.aifb.ldstream.learner.dao;

import java.io.Serializable;
import java.util.Arrays;

import org.openrdf.model.URI;

import edu.kit.aifb.ldstream.stat.distrib.IDistribution;

public class ValueDistributionResult implements Serializable{


	private static final long serialVersionUID = -3295678300843033441L;

	private URI className;
	private URI propName;
	private IDistribution distribution;
	// used to map the distribution results to the linked literals
	private String[] valueMapping;
	
	public ValueDistributionResult(URI className, URI propName, IDistribution distribution) {
		this.className = className;
		this.propName = propName;
		this.distribution = distribution;
	}
	public ValueDistributionResult(URI className, URI propName, IDistribution distribution, String[] valueMapping) {
		this.className = className;
		this.propName = propName;
		this.distribution = distribution;
		this.valueMapping = valueMapping;
	}
	
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("The values of the ");
		sb.append(this.propName.stringValue());
		sb.append(" of the class ");
		sb.append(this.className.stringValue());
		sb.append(" are distributed: ");
		sb.append(this.distribution.toString());
		return sb.toString();
	}
	
	public int hashCode(){
		return this.className.hashCode() * this.propName.hashCode();
	}
	
	public boolean equals(Object o){
		if(o instanceof ValueDistributionResult){
			ValueDistributionResult vdr = (ValueDistributionResult) o;
			if(vdr.className != null && vdr.className.equals(this.className)){
				if(vdr.propName != null && vdr.propName.equals(this.propName)){
					return true;
					// distribution should be the same otherwise something went terribly wrong...
				}
			}
		}
		return false;
	}
	/**
	 * @return the className
	 */
	public URI getClassName() {
		return className;
	}
	/**
	 * @param className the className to set
	 */
	public void setClassName(URI className) {
		this.className = className;
	}
	/**
	 * @return the propName
	 */
	public URI getPropName() {
		return propName;
	}
	/**
	 * @param propName the propName to set
	 */
	public void setPropName(URI propName) {
		this.propName = propName;
	}
	/**
	 * @return the distribution
	 */
	public IDistribution getDistribution() {
		return distribution;
	}
	/**
	 * @param distribution the distribution to set
	 */
	public void setDistribution(IDistribution distribution) {
		this.distribution = distribution;
	}
	
	public String[] getValueMapping(){
		return Arrays.copyOf(valueMapping, valueMapping.length);
	}
	
	/**
	 * @return the valueMapping
	 */
	public String getValueMapping(int index) {
		return valueMapping[index % this.valueMapping.length];
	}
	/**
	 * Returns true if the ValueDistributionResult has a ValueMapping => The property links to a discrete string value
	 * @return true if ValueMapping exists.
	 */
	public boolean hasValueMapping(){
		return this.valueMapping != null;
	}
}
